4750 #include "types.h"
4751 #include "defs.h"
4752 #include "param.h"
4753 #include "fs.h"
4754 #include "file.h"
4755 #include "spinlock.h"
4756 
4757 struct devsw devsw[NDEV];
4758 struct {
4759   struct spinlock lock;
4760   struct file file[NFILE];
4761 } ftable;
4762 
4763 void
4764 fileinit(void)
4765 {
4766   initlock(&ftable.lock, "ftable");
4767 }
4768 
4769 // Allocate a file structure.
4770 struct file*
4771 filealloc(void)
4772 {
4773   struct file *f;
4774 
4775   acquire(&ftable.lock);
4776   for(f = ftable.file; f < ftable.file + NFILE; f++){
4777     if(f->ref == 0){
4778       f->ref = 1;
4779       release(&ftable.lock);
4780       return f;
4781     }
4782   }
4783   release(&ftable.lock);
4784   return 0;
4785 }
4786 
4787 // Increment ref count for file f.
4788 struct file*
4789 filedup(struct file *f)
4790 {
4791   acquire(&ftable.lock);
4792   if(f->ref < 1)
4793     panic("filedup");
4794   f->ref++;
4795   release(&ftable.lock);
4796   return f;
4797 }
4798 
4799 
4800 // Close file f.  (Decrement ref count, close when reaches 0.)
4801 void
4802 fileclose(struct file *f)
4803 {
4804   struct file ff;
4805 
4806   acquire(&ftable.lock);
4807   if(f->ref < 1)
4808     panic("fileclose");
4809   if(--f->ref > 0){
4810     release(&ftable.lock);
4811     return;
4812   }
4813   ff = *f;
4814   f->ref = 0;
4815   f->type = FD_NONE;
4816   release(&ftable.lock);
4817 
4818   if(ff.type == FD_PIPE)
4819     pipeclose(ff.pipe, ff.writable);
4820   else if(ff.type == FD_INODE)
4821     iput(ff.ip);
4822 }
4823 
4824 // Get metadata about file f.
4825 int
4826 filestat(struct file *f, struct stat *st)
4827 {
4828   if(f->type == FD_INODE){
4829     ilock(f->ip);
4830     stati(f->ip, st);
4831     iunlock(f->ip);
4832     return 0;
4833   }
4834   return -1;
4835 }
4836 
4837 
4838 
4839 
4840 
4841 
4842 
4843 
4844 
4845 
4846 
4847 
4848 
4849 
4850 // Read from file f.  Addr is kernel address.
4851 int
4852 fileread(struct file *f, char *addr, int n)
4853 {
4854   int r;
4855 
4856   if(f->readable == 0)
4857     return -1;
4858   if(f->type == FD_PIPE)
4859     return piperead(f->pipe, addr, n);
4860   if(f->type == FD_INODE){
4861     ilock(f->ip);
4862     if((r = readi(f->ip, addr, f->off, n)) > 0)
4863       f->off += r;
4864     iunlock(f->ip);
4865     return r;
4866   }
4867   panic("fileread");
4868 }
4869 
4870 // Write to file f.  Addr is kernel address.
4871 int
4872 filewrite(struct file *f, char *addr, int n)
4873 {
4874   int r;
4875 
4876   if(f->writable == 0)
4877     return -1;
4878   if(f->type == FD_PIPE)
4879     return pipewrite(f->pipe, addr, n);
4880   if(f->type == FD_INODE){
4881     ilock(f->ip);
4882     if((r = writei(f->ip, addr, f->off, n)) > 0)
4883       f->off += r;
4884     iunlock(f->ip);
4885     return r;
4886   }
4887   panic("filewrite");
4888 }
4889 
4890 
4891 
4892 
4893 
4894 
4895 
4896 
4897 
4898 
4899 
